package cn.b.sky.user;

import cn.b.sky.user.enums.ResourceTypeCode;
import cn.b.sky.user.enums.UserTypeEnums;
import cn.b.sky.user.service.SecurityService;
import cn.b.sky.user.service.TimeZoneService;
import cn.b.sky.user.service.model.MenuInfo;
import cn.b.sky.user.service.model.TimeZone;
import cn.b.sky.user.service.model.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;


@Service
public class MyUserDetailsService implements UserDetailsService {

  @Resource
  private SecurityService securityService;

  @Resource
  private TimeZoneService timeZoneService;


  @Override
  public UserDetails loadUserByUsername(String username) {

    if (StringUtils.isBlank(username)) {
      throw new RuntimeException("用户名为空!");
    }
    //用户名+"_"+工厂代码+"_"+语言
    if (username.indexOf(Constants.LONGIN_SPLIT) > 0) {
      String[] str = username.split(Constants.LONGIN_SPLIT);
      if (securityService.checkSiteIsLocked(str[1])) {
        throw new RuntimeException("工厂不存在或已锁定!");
      }
      UserInfo userInfo = securityService.loadUser(str[1], str[0]);
      if (null == userInfo) {
        throw new RuntimeException("工厂或用户名不正确!");
      }
      if (UserTypeEnums.NLI.getValue().equals(userInfo.getUserTypeECode())) {
        throw new RuntimeException("非登录用户，不能登录!");
      }
      //缓存用户权限
      cacheUserGrant(userInfo);
      userInfo.setSiteCode(str[1]);
      //缓存用户对应的java时区ID
      TimeZone timezone = timeZoneService.selectTimeZoneByCode(userInfo.getTimeZoneCode());
      if (timezone != null) {
        userInfo.setJavaTimeZoneId(timezone.getJavaTimeZoneId());
      }
      if (str.length == 3) {
        userInfo.setLanguageCode(str[2]);
      }
      return userInfo;
    } else {
      throw new RuntimeException("请输入工厂代码!");
    }
  }

  /**
   * 
   * <strong>Title : cacheUserGrant<br></strong>
   * <strong>Description : </strong>缓存用户权限<br> 
   * <strong>Create on : 2017-3-7 上午11:12:54<br></strong>
   * <p>
   * @param userInfo
   * void
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  private void cacheUserGrant(UserInfo userInfo) {
    //菜单权限
    Collection<GrantedAuthority> auths = new HashSet<GrantedAuthority>();
    //按钮权限
    Collection<GrantedAuthority> buttonAuths = new HashSet<GrantedAuthority>();
    //超级管理员拥有所有的权限
    if (userInfo.isAdministrator()) {
      auths.add(new SimpleGrantedAuthority(MyAccessDecisionManager.ALLACCESSDECIDION));
      buttonAuths.add(new SimpleGrantedAuthority(MyAccessDecisionManager.ALLACCESSDECIDION));
    } else {
      //菜单权限
      List<MenuInfo> menus = this.securityService.listMenuByUsername(userInfo.getUsername());
      for (MenuInfo item : menus) {
        if (item.getResourceTypeECode().equals(ResourceTypeCode.FORM.getValue())) {
          GrantedAuthority auth = new SimpleGrantedAuthority(Constants.ROLEPREFIX + item.getMenuCode());
          auths.add(auth);
        } else if (item.getResourceTypeECode().equals(ResourceTypeCode.BUTN.getValue())) {
          GrantedAuthority auth = new SimpleGrantedAuthority(Constants.BOTTONPREFIX + item.getMenuCode());
          buttonAuths.add(auth);
        }
      }
    }
    userInfo.setAuthorities(auths);
    //缓存用户的button权限
    userInfo.setButtonAuthorities(buttonAuths);
  }
}
